#include "serializer/io.h"
#include "serializer/serializer.h"

#include <gtest/gtest.h>

#include <string>
#include <vector>

using namespace serializer;

// 目标：验证 ADL 绑定健壮性 —— 自定义类型在其命名空间中定义的 tag_invoke 能被统一的 CPO
// 接口稳定发现
namespace user_models
{
struct AdlBoundType
{
    int id;
    std::string name;
    bool operator==(const AdlBoundType & other) const
    {
        return id == other.id && name == other.name;
    }
};

/**
 * AdlBoundType 的序列化 tag_invoke 实现（位于类型所在的命名空间，供 ADL 发现）
 * 参数:
 * - writer 写入器，满足 writer 概念
 * - value 要序列化的对象
 * - options 序列化选项
 * 返回值: 无
 * 异常: 由底层 writer 或其他序列化逻辑抛出
 */
template <typename Writer, typename Options>
void
tag_invoke(serialize_tag_t, Writer & writer, const AdlBoundType & value, const Options & options)
{
    // 简单序列化两个字段
    tag_invoke_fn(serialize_tag, writer, value.id, options);
    tag_invoke_fn(serialize_tag, writer, value.name, options);
}

/**
 * AdlBoundType 的反序列化 tag_invoke 实现（位于类型所在的命名空间，供 ADL 发现）
 * 参数:
 * - reader 读取器，满足 reader 概念
 * - options 序列化选项
 * 返回值: 反序列化得到的 AdlBoundType 对象
 * 异常: 由底层 reader 或其他反序列化逻辑抛出
 */
template <typename Reader,
          typename Options,
          typename std::enable_if<serializer::reader<Reader> &&
                                      serializer::serialization_options<Options>,
                                  int>::type = 0>
AdlBoundType
tag_invoke(deserialize_tag_t<AdlBoundType>, Reader & reader, const Options & options)
{
    AdlBoundType result{};
    result.id = tag_invoke_fn(deserialize_tag<int>, reader, options);
    result.name = tag_invoke_fn(deserialize_tag<std::string>, reader, options);
    return result;
}
} // namespace user_models

TEST(cpo_adl_binding_test, adl_finds_user_defined_tag_invoke_in_type_namespace)
{
    vector_writer writer;
    default_options options{};

    user_models::AdlBoundType original{7, "bob"};
    serialize(writer, original, options);

    vector_reader reader(writer.data());
    user_models::AdlBoundType deserialized = deserialize(reader, options);
    EXPECT_EQ(original, deserialized);
}

TEST(cpo_adl_binding_test, default_implementations_for_builtin_and_containers_are_stable)
{
    vector_writer writer;
    default_options options{};

    // 基础类型 + 容器默认实现
    std::vector<int> vec{1, 2, 3, 4, 5};
    serialize(writer, vec, options);

    vector_reader reader(writer.data());
    std::vector<int> vec_out = deserialize(reader, options);
    EXPECT_EQ(vec, vec_out);
}

TEST(cpo_adl_binding_test, options_are_respected_in_default_impls)
{
    vector_writer writer;
    default_options options{};

    // 验证字节序选项在默认实现中生效
    int value = 0x01020304;
    auto le = options.with_byte_order(byte_order::little_endian);
    auto be = options.with_byte_order(byte_order::big_endian);

    writer.clear();
    // 小端：容器路径，写入一个只包含 value 的向量
    serialize(writer, std::vector<int>{value}, le);
    vector_reader reader_le(writer.data());
    std::vector<int> v_le = deserialize(reader_le, le);
    EXPECT_EQ(value, v_le[0]);

    writer.clear();
    // 大端：基础类型路径
    serialize(writer, value, be);
    vector_reader reader_be(writer.data());
    int v_be = deserialize(reader_be, be);
    EXPECT_EQ(value, v_be);
}
